package com.xcity.game.player;

import java.text.MessageFormat;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.slf4j.Logger;

import com.xcity.db.entity.Build;
import com.xcity.db.entity.Land;
import com.xcity.db.entity.Player;
import com.xcity.db.entity.Relation2;
import com.xcity.game.account.AccountChannel;
import com.xcity.game.build.BuildLevelUpTemplate;
import com.xcity.game.build.BuildTemplate;
import com.xcity.game.buildv2.BuildV2;
import com.xcity.game.buildv2.BuildV2.State;
import com.xcity.game.common.Cause;
import com.xcity.game.common.GameStaticConfig;
import com.xcity.game.common.MessageConst;
import com.xcity.game.common.PlayerPool;
import com.xcity.game.conquests.Conquest;
import com.xcity.game.event.GameEvents;
import com.xcity.game.item.effect.AddCharmEffect.CharmDeltaType;
import com.xcity.game.land.LandBuyTemplate;
import com.xcity.game.land.LandService;
import com.xcity.game.land.LandTemplate;
import com.xcity.game.mail.MailService;
import com.xcity.game.player.template.DestinyTemplate;
import com.xcity.game.player.template.PlayerLevelTemplate;
import com.xcity.game.relation.RelationService;
import com.xcity.game.vip.VipTemplate;
import com.xcity.game.vip.VipUtils;
import com.xcity.pomelo.push.SyncPush;
import com.xcity.pomelo.push.sync.IntSync;
import com.xcity.pomelo.push.sync.MapSync;
import com.xcity.util.ExpCalc2;
import com.xcity.util.PlatformApi;

import naga.x.App;
import naga.x.game.template.TemplateService;
import naga.x.game.time.TimeUpdater;
import naga.x.util.CommonUtils;
import naga.x.util.IOUtils;
import naga.x.util.StringUtils;
import naga.x.util.TimeUtils;

public class PlayerUtils {

	private static List<PlayerLevelTemplate> templates;
	private static ExpCalc2 expCalc; // 经验计算器
//	public static final int MAX_LEVEL;
	public static final Logger LOG = PlayerService.LOG;
	static {
		templates = App.getApp().getServiceManager().get(TemplateService.class).getTemplatesList(PlayerLevelTemplate.class);
//		Collections.sort(templates);
//		MAX_LEVEL = templates.size();
		int size = templates.size();
		int[] exps = new int[size];
		for (int i = 0; i < size; i++) {
			exps[i] = templates.get(i).getExp();
		}
		expCalc = new ExpCalc2(exps);
	}
	
//	/**
//	 * 根据经验计算等级
//	 * @param exp
//	 * @return
//	 */
//	public static int exp2Lvl(long exp) {
//		List<PlayerLevelTemplate> temps = templates;
//		for (int i = 0, size = temps.size(); i < size; i++) {
//			PlayerLevelTemplate temp = temps.get(i);
//			if (exp < temp.getExp()) {
//				return i;
//			}
//			exp -= temp.getExp();
//		}
//		return MAX_LEVEL;
//	}
//	
//	/**
//	 * 根据总经验计算在当前等级范围内的经验
//	 * @param exp
//	 * @return
//	 */
//	public static int getExpOfNowLvl(long exp) {
//		List<PlayerLevelTemplate> temps = templates;
//		for (int i = 0, size = temps.size(); i < size; i++) {
//			PlayerLevelTemplate temp = temps.get(i);
//			if (exp < temp.getExp()) {
//				break;
//			}
//			exp -= temp.getExp();
//		}
//		return (int) exp;
//	}
//	
//	/**
//	 * 获取下一等级所需经验
//	 * @param nowLvl
//	 * @return
//	 */
//	public static int getNextLvlNeedExp(int nowLvl) {
//		if (nowLvl >= MAX_LEVEL || nowLvl <= 0) {
//			return Integer.MAX_VALUE;
//		}
//		return templates.get(nowLvl).getExp();
//	}
	
	/**
	 * 获取当前等级可建造的最大建筑数量
	 * @param level
	 * @return
	 */
	@Deprecated
	public static int getMaxBuildNum(int level) {
		if (level < 1) {
			return 0;
		}
		if (level > expCalc.getMaxLevel()) {
			level = expCalc.getMaxLevel();
		}
		return templates.get(level - 1).getMaxBuildNum();
	}
	
	/**
	 * 下一档次的最大建筑数量
	 * @param nowMaxBuildNum
	 * @return
	 */
	@Deprecated
	public static int getMaxBuildNumOfNextGrade(int nowMaxBuildNum) {
		List<PlayerLevelTemplate> temps = templates;
		int size = temps.size();
		for (int i = 0; i < size; i++) {
			PlayerLevelTemplate temp = temps.get(i);
			if (temp.getMaxBuildNum() > nowMaxBuildNum) {
				return temp.getMaxBuildNum();
			}
		}
		return temps.get(size - 1).getMaxBuildNum();
	}
	
	/**
	 * 达到该最大建筑数量所需最低等级
	 * @param maxBuildNum
	 * @return
	 */
	@Deprecated
	public static int getMaxBuildNumNeedLvl(int maxBuildNum) {
		List<PlayerLevelTemplate> temps = templates;
		for (int i = 0, size = temps.size(); i < size; i++) {
			PlayerLevelTemplate temp = temps.get(i);
			if (temp.getMaxBuildNum() >= maxBuildNum) {
				return temp.getLevel();
			}
		}
		return expCalc.getMaxLevel();
	}
	
	@Deprecated
	public static int calcRisk(List<Build> buildings) {
		int size;
		int risk = 0;
		if (buildings != null && (size = buildings.size()) > 0) {
			for (int i = 0; i < size; i++) {
				Build b = buildings.get(i);
				BuildTemplate temp = b.getTemplate();
				BuildLevelUpTemplate tempLv;
				if (temp != null && (tempLv = temp.getLevelUpTemplate(b.getLevel())) != null) {
					risk += tempLv.getRisk();
				}
			}
		}
		return risk;
	}
	
	@Deprecated
	public static long calcFixedAssets(List<Build> buildings) {
		int size;
		long val = 0;
		if (buildings != null && (size = buildings.size()) > 0) {
			for (int i = 0; i < size; i++) {
				Build b = buildings.get(i);
				BuildTemplate temp = b.getTemplate();
				BuildLevelUpTemplate tempLv;
				if (temp != null && (tempLv = temp.getLevelUpTemplate(b.getLevel())) != null) {
					val += tempLv.getPrice();
				}
			}
		}
		return val;
	}
	
	@Deprecated
	public static long calcFixedAssets(long playerId, List<Build> buildings) {
		// build
		long val = calcFixedAssets(buildings);
		// land
		LandService service = App.getApp().getServiceManager().get(LandService.class);
		if (service == null) {
			return val;
		}
		int size;
		List<Land> lands = service.getPlayerLands(playerId);
		if ((size = lands.size()) > 0) {
			for (int i = 0; i < size; i++) {
				Land land = lands.get(i);
				LandTemplate temp = land.getTemplate();
				LandBuyTemplate tempBuy;
				if (temp != null && (tempBuy = temp.getBuyTemplate(land.getLevel())) != null) {
					val += tempBuy.getPrice();
				}
			}
		}
		return val;
	}
	
	/**
	 * 计算固定资产
	 * @param player
	 * @return
	 */
	public static long calcFixedAssets(Player player) {
		long value = 0;
		List<BuildV2> buildings = player.getBuildings2().getBuildings();
		for (int i = 0; i < buildings.size(); i++) {
			BuildV2 building = buildings.get(i);
			if (building.getState() == State.BUILT) {
				value += building.getTemplate().getWorth();
			}
		}
		// 计算占领的建筑固资
		if (player.getConquests() != null) { // robot's null
			List<Conquest> cqts = player.getConquests().getConquests();
			for (int i = 0; i < player.getConquests().size(); i++) {
				Conquest cqt = cqts.get(i);
				BuildV2 building = cqt.ref2();
				if (building != null) {
					value += building.getTemplate().getWorth();
				}
			}
		}
		return value;
	}
	
	/**
	 * 获取好友数量上限
	 * @param player
	 * @return
	 */
	public static int getFriendsNumMax(Player player) {
		VipTemplate vt = VipUtils.getTemplate(player.getVipLvl());
		return vt != null ? vt.getFriendsMaxNum() : 10;
	}
	
//	public static String filterIcon(String icon, byte sex) {
//		if (StringUtils.isNotEmpty(icon) && icon.startsWith("http")) {
//			return CommonUtils.decodeURL(icon, IOUtils.UTF8);
//		}
//		return sex == Player.MALE ? Player.DEFAULT_ICON : Player.DEFAULT_FEMALE_ICON;
//	}
	
	public static String mappingIcon(AccountChannel channel, String iconUrl, byte sex) {
		if (StringUtils.isNotEmpty(iconUrl) && iconUrl.startsWith("http")) {
			iconUrl = CommonUtils.decodeURL(iconUrl, IOUtils.UTF8);
			if (channel != null && !iconUrl.startsWith(PlatformApi.resourceServerUrl)) {
				return PlatformApi.mappingIcon(channel, iconUrl);
			}
			return iconUrl;
		}
		return sex == Player.MALE ? Player.DEFAULT_ICON : Player.DEFAULT_FEMALE_ICON;
	}
	
//	/**
//	 * 角色血量
//	 * @param player
//	 * @return
//	 */
//	public static int getHP(Player player) {
//		return getTemplate(player).getHp() + getAQ(player) * 5;
//	}
//	
//	/**
//	 * 角色攻击力
//	 * @param player
//	 * @return
//	 */
//	public static int getAttack(Player player) {
////		return getTemplate(player).getDps();
//		return getIQ(player);
//	}
//	
//	public static float getDefense(Player player) {
//		return getIQ(player) * 0.714f;
//	}
	
	/**
	 * 基础血量
	 * @param player
	 * @return
	 */
	@Deprecated
	public static int getBaseHp(Player player) {
		return getTemplate(player).getHp();
	}
	
	public static int getMaxStrength(Player player) {
		return getTemplate(player).getMaxStrength();
	}
	
	public static int getMaxVigour(Player player) {
		return getTemplate(player).getMaxVigour();
	}
	
	//---老版主属性废弃---
	@Deprecated
	public static int getIQ(Player player) {
		return getTemplate(player).getIQ();
	}
	
	@Deprecated
	public static int getEQ(Player player) {
		return getTemplate(player).getEQ();
	}
	
	@Deprecated
	public static int getAQ(Player player) {
		return getTemplate(player).getAQ();
	}
	//---老版主属性废弃---
	
	//---新版主属性v2---
//	/** 力量 */
//	@Deprecated
//	public static float getSTR(Player player) {
//		return CombatUtils.strInit + (player.getLevel() - 1) * CombatUtils.strDelta;
//	}
//
//	/** 智力 */
//	@Deprecated
//	public static float getINT(Player player) {
//		return CombatUtils.intInit + (player.getLevel() - 1) * CombatUtils.intDelta;
//	}
//	
//	/** 敏捷 */
//	@Deprecated
//	public static float getAGI(Player player) {
//		return CombatUtils.agiInit + (player.getLevel() - 1) * CombatUtils.agiDelta;
//	}
//	
//	/** 精神 */
//	@Deprecated
//	public static float getSPI(Player player) {
//		return CombatUtils.spiInit + (player.getLevel() - 1) * CombatUtils.spiDelta;
//	}
//	
//	/** 耐力 */
//	@Deprecated
//	public static float getSTA(Player player) {
//		return CombatUtils.staInit + (player.getLevel() - 1) * CombatUtils.staDelta;
//	}
	//---新版主属性v2---
	
	public static PlayerLevelTemplate getTemplate(Player player) {
		int index = player.getLevel() - 1;
		if (index < 0) {
			index = 0;
		} else if (index >= expCalc.getMaxLevel()) {
			index = expCalc.getMaxLevel() - 1;
		}
		return templates.get(index);
	}
	
	/**
	 * 角色统御力<br/>
	 * 统御力=人物等级*5+建筑物等级和*1.4286，保留小数点0位
	 * @param player
	 */
	@Deprecated
	public static int getLeadership(Player player) {
//		List<Build> buildings = player.getBuildings().getBuildings();
//		int buildLvl = 0;
//		for (int i = 0, size = buildings.size(); i < size; i++) {
//			buildLvl += buildings.get(i).getLevel();
//		}
//		return (int) (player.getLevel() * 5 + buildLvl * 1.4286f);
		return 0;
	}
	
	/**
	 * 可携带员工数量上限<br/>
	 * 可持有员工数量=统御力/10
	 * @param player
	 * @return
	 */
	public static int getEmployeeCapcity(Player player) {
//		int c = getLeadership(player) / 10;
//		return c > 5 ? c : 5;
		return -1; // 不限制
	}
	
	
//	private static final float[] PLAYER_FACTORS = new float[] { 1f, 1f, 1f, 1.03f, 1.06f, 1.09f, 1.12f, 1.15f };
	/**
	 * <pre>
	 * 角色加成系数
	 * 人物等级30系数1 1.03
	 * 人物等级40系数2 1.06
	 * 人物等级50系数3 1.09
	 * 人物等级60系数4 1.12
	 * 人物等级70系数5 1.15
	 * </pre>
	 * @param player
	 * @return
	 */
	@Deprecated
	public static float getPlayerFactor(Player player) {
//		int index = player.getLevel() / 10;
//		float[] factors = PLAYER_FACTORS;
//		int len = factors.length;
//		return factors[index >= len ? len - 1 : index];
		return 1f;
	}
	
	/**
	 * 获取玩家建造队列最大值(可通过提升vip等级增加该值)
	 * @param player
	 * @return
	 */
	public static int getBuildQueueMaxSize(Player player) {
		return Build.BUILD_QUEUE_BASIC_SIZE + player.getPool().getIntValue(PlayerPool.PROPERTY_EXTEND_BUILD_QUEUE_SIZE);
	}
	
	public static final int TAP_LIKE_NUM_EVERY_DAY = 10;
	/**
	 * 获取今日剩余点赞次数
	 * @param player
	 * @return
	 */
	public static int getLeftTapLikeTimes(Player player) {
		int lastDay = player.getPool().getIntValue(PlayerPool.PROPERTY_LAST_TAP_LIKE_DAY);
		if (lastDay != TimeUpdater.getInstance().today()) {
			return TAP_LIKE_NUM_EVERY_DAY;
		}
		int n = player.getPool().getIntValue(PlayerPool.PROPERTY_TAP_LIKE_NUM);
		n = TAP_LIKE_NUM_EVERY_DAY - n;
		return n > 0 ? n : 0;
	}
	
	/**
	 * 点赞
	 * @param player
	 * @param target
	 * @param relation
	 */
	public static void tapLike(Player player, Player target, Relation2 relation) {
		boolean isFriend = relation != null && relation.getType() == Relation2.TYPE_FRIEND;
//		// 给自己加魅力
//		addCharm(player, isFriend ? GameStaticConfig.TAP_LIKE_FRIEND_ADD_SELF_CHARM : GameStaticConfig.TAP_LIKE_OTHER_ADD_SELF_CHARM, Cause.TAP_LIKE, CharmDeltaType.UNKNOWN);
		// 好友之间增加亲密度
		if (isFriend) {
			relation.addIntimacy(Relation2.TAP_LIKE_ADD_INTIMACY, Cause.TAP_LIKE);
		} else {
			// 给对方加魅力
			validateCharm(target);
			addCharm(target, GameStaticConfig.TAP_LIKE_ADD_TARGET_CHARM, Cause.BE_TAPPED_LIKE, CharmDeltaType.TAP_LIKE);
		}
		
		// 累计点赞次数
		int lastDay = player.getPool().getIntValue(PlayerPool.PROPERTY_LAST_TAP_LIKE_DAY);
		int n = player.getPool().getIntValue(PlayerPool.PROPERTY_TAP_LIKE_NUM);
		if (lastDay != TimeUpdater.getInstance().today()) {
			player.poolSet(PlayerPool.PROPERTY_LAST_TAP_LIKE_DAY, TimeUpdater.getInstance().today());
			player.poolSet(PlayerPool.PROPERTY_TAP_LIKE_PLAYERS, new LinkedHashSet<Long>());
			n = 0;
		}
		Set<Long> playerIds = player.getPool().getObject(PlayerPool.PROPERTY_TAP_LIKE_PLAYERS, Set.class);
		if (playerIds == null) {
			playerIds = new LinkedHashSet<Long>();
			player.poolSet(PlayerPool.PROPERTY_TAP_LIKE_PLAYERS, playerIds);
		}
		playerIds.add(target.getId());
		player.poolSet(PlayerPool.PROPERTY_TAP_LIKE_NUM, n + 1);
		App.getApp().getEventManager().addEvent(GameEvents.EVENT_TAP_LIKE, player, target, isFriend);
	}
	
	/**
	 * 检测今日是否给目标玩家点过赞
	 * @param player
	 * @param target
	 * @return
	 */
	public static boolean wasTappedLike(Player player, long target) {
		int lastDay = player.getPool().getIntValue(PlayerPool.PROPERTY_LAST_TAP_LIKE_DAY);
		if (lastDay != TimeUpdater.getInstance().today()) {
			return false;
		}
		Set<Long> playerIds = player.getPool().getObject(PlayerPool.PROPERTY_TAP_LIKE_PLAYERS, Set.class);
		return playerIds != null && playerIds.contains(target);
	}
	
	public static int getCharm(Player player) {
		return player.getPool().getIntValue(PlayerPool.PROPERTY_CHARM);
	}
	
	public static boolean addCharm(Player player, int val, String cause, CharmDeltaType type) {
		int oldVal = player.getPool().getIntValue(PlayerPool.PROPERTY_CHARM);
		if (oldVal + val <= 0) {
			return false;
		}
		int newVal = player.poolAdd(PlayerPool.PROPERTY_CHARM, val);
		if (player.isOnline()) {
			player.send(new MapSync(SyncPush.SYNC_CHARM, type.ordinal(), newVal));
		}
		App.getApp().getEventManager().addEvent(GameEvents.EVENT_CHARM_CHANGED, player, newVal);
		LOG.info("[ADDCHARM]ID[{}]OLD[{}]NEW[{}]CAUSE[{}]", player.getId(), oldVal, newVal, cause);
		return true;
	}
	
	public static boolean decCharm(Player player, int val, String cause) {
		int oldVal = player.getPool().getIntValue(PlayerPool.PROPERTY_CHARM);
		if (oldVal <= 0 || val <= 0) {
			return false;
		}
		int newVal = player.poolSubtract(PlayerPool.PROPERTY_CHARM, val);
		if (newVal < 0) {
			player.poolSet(PlayerPool.PROPERTY_CHARM, 0);
			newVal = 0;
		}
		if (player.isOnline()) {
			player.send(new IntSync(SyncPush.SYNC_CHARM, newVal));
		}
		App.getApp().getEventManager().addEvent(GameEvents.EVENT_CHARM_CHANGED, player, newVal);
		LOG.info("[DECCHARM]ID[{}]OLD[{}]NEW[{}]CAUSE[{}]", player.getId(), oldVal, newVal, cause);
		return true;
	}
	
	/**
	 * 玩家魅力值不足5千万时，15天未登录则每天减少100点魅力值
	 * 玩家魅力值超过(含)5千万时，30天未登录则每天减少50点魅力值
	 * @param player
	 */
	public static void validateCharm(Player player) {
		// 计算未登录导致的魅力值掉落
		int charm = getCharm(player);
		if (charm <= 0) {
			return;
		}
		int decDays = TimeUpdater.getInstance().today() - player.getPool().getIntValue(PlayerPool.PROPERTY_LAST_DEC_CHARM_DAY);
		if (decDays <= 0) {
			return;
		}
		Date d = TimeUtils.getRecentDate(player.getLastLoginTime(), player.getLastLogoutTime());
		int noLoginDays = TimeUtils.diffDay(d, TimeUpdater.getInstance().now());
		int diff = noLoginDays - (charm < 50000000 ? 15 : 30);
		if (diff <= 0) {
			return;
		}
		if (decDays > diff) {
			decDays = diff;
		}
		int val = charm < 50000000 ? 100 : 50;
		decCharm(player, decDays * val, Cause.NO_LOGIN);
		player.poolSet(PlayerPool.PROPERTY_LAST_DEC_CHARM_DAY, TimeUpdater.getInstance().today());
	}
	
	/**
	 * 获取剩余购买体力次数
	 * @param player
	 * @return
	 */
	public static int getLeftBuyStrengthTimes(Player player) {
		VipTemplate vt = VipUtils.getTemplate(player.getVipLvl());
		if (vt == null) {
			return 0;
		}
		int lastDay = player.getPool().getIntValue(PlayerPool.PROPERTY_LAST_BUY_STRENGTH_DAY);
		if (lastDay != TimeUpdater.getInstance().today()) {
			return vt.getBuyStrNum();
		}
		int n = vt.getBuyStrNum() - player.getPool().getIntValue(PlayerPool.PROPERTY_BOUGHT_STRENGTH_TIMES);
		return n > 0 ? n : 0;
	}
	
	/**
	 * 获取今日已购买体力次数
	 * @param player
	 * @return
	 */
	public static int getBoughtStrengthTimes(Player player) {
		int lastDay = player.getPool().getIntValue(PlayerPool.PROPERTY_LAST_BUY_STRENGTH_DAY);
		if (lastDay != TimeUpdater.getInstance().today()) {
			return 0;
		}
		return player.getPool().getIntValue(PlayerPool.PROPERTY_BOUGHT_STRENGTH_TIMES);
	}
	
	/**
	 * 获取每日最多可购买体力次数
	 * @param player
	 * @return
	 */
	public static int getBuyStrengthMaxTimes(Player player) {
		VipTemplate vt = VipUtils.getTemplate(player.getVipLvl());
		if (vt == null) {
			return 0;
		}
		return vt.getBuyStrNum();
	}
	
	/**
	 * 记录购买体力次数
	 * @param player
	 * @param n
	 */
	public static void countBuyStrength(Player player, int n) {
		int lastDay = player.getPool().getIntValue(PlayerPool.PROPERTY_LAST_BUY_STRENGTH_DAY);
		int total = player.getPool().getIntValue(PlayerPool.PROPERTY_BOUGHT_STRENGTH_TIMES);
		if (lastDay != TimeUpdater.getInstance().today()) {
			player.poolSet(PlayerPool.PROPERTY_LAST_BUY_STRENGTH_DAY, TimeUpdater.getInstance().today());
			total = 0;
		}
		player.poolSet(PlayerPool.PROPERTY_BOUGHT_STRENGTH_TIMES, total + n);
	}
	
	public static boolean wasPresentedStrength(Player player, long target) {
		return getPresentedStrengthIds(player).contains(target);
	}
	
	public static Set<Long> getPresentedStrengthIds(Player player) {
		int lastDay = player.getPool().getIntValue(PlayerPool.PROPERTY_LAST_PRESENT_STRENGTH_DAY);
		if (lastDay != TimeUpdater.getInstance().today()) {
			return Collections.emptySet();
		}
		Set<Long> ids = player.getPool().getObject(PlayerPool.PROPERTY_PRESENT_STRENGTH_PLAYERS, Set.class);
		return ids != null ? ids : Collections.emptySet();
	}
	
	/** 获取该玩家今日受赠体力总数 */
	public static int getBePresentedStrength(Player player) {
		int day = player.getPool().getIntValue(PlayerPool.PROPERTY_LAST_BE_PRESENTED_STRENGTH_DAY);
		if (day != TimeUpdater.getInstance().today()) {
			return 0;
		}
		return player.getPool().getIntValue(PlayerPool.PROPERTY_BE_PRESENTED_STRENGTH_VAL);
	}
	
	public static String presentStrength(Player source, Player target) {
		return presentStrength(App.getApp().getServiceManager().get(RelationService.class), source, target);
	}
	
	public static String presentStrength(RelationService service, Player source, Player target) {
		Set<Long> presenteds = getPresentedStrengthIds(source);
		// 检测是否已赠送过目标玩家
		if (presenteds.contains(target.getId())) {
			return MessageConst.HAVE_PRESENTED_STRENGTH;
		}
		// 检测今日赠送次数是否已达上限
		int maxVal = getFriendsNumMax(source);
		if (presenteds.size() >= maxVal) {
			return MessageFormat.format(MessageConst.PRESENTED_STRENGTH_MAXED, maxVal);
		}
		// 检测是否为好友
		if (!service.isFriend(source, target, true)) {
			return MessageConst.CAN_NOT_PRESENT_STRENGTH_TO_STRANGER;
		}
		// 检测目标玩家受赠体力是否已达上限
		maxVal = getFriendsNumMax(target) * GameStaticConfig.presentStr;
		if (getBePresentedStrength(target) >= maxVal) {
			return MessageConst.TARGET_BE_PRESENTED_STRENGTH_MAXED;
		}
		int today = TimeUpdater.getInstance().today();
		// 记录赠送玩家id
		Set<Long> ids = source.getPool().getObject(PlayerPool.PROPERTY_PRESENT_STRENGTH_PLAYERS, Set.class);
		if (today != source.getPool().getIntValue(PlayerPool.PROPERTY_LAST_PRESENT_STRENGTH_DAY)) {
			source.poolSet(PlayerPool.PROPERTY_LAST_PRESENT_STRENGTH_DAY, today);
			source.poolSet(PlayerPool.PROPERTY_PRESENT_STRENGTH_PLAYERS, ids = new LinkedHashSet<Long>());
		}
		if (ids == null) {
			source.poolSet(PlayerPool.PROPERTY_PRESENT_STRENGTH_PLAYERS, ids = new LinkedHashSet<Long>());
		}
		ids.add(target.getId());
		// 记录受赠者累计点数
		int val = target.getPool().getIntValue(PlayerPool.PROPERTY_BE_PRESENTED_STRENGTH_VAL);
		if (today != target.getPool().getIntValue(PlayerPool.PROPERTY_LAST_BE_PRESENTED_STRENGTH_DAY)) {
			target.poolSet(PlayerPool.PROPERTY_LAST_BE_PRESENTED_STRENGTH_DAY, today);
			val = 0;
		}
		val += GameStaticConfig.presentStr;
		target.poolSet(PlayerPool.PROPERTY_BE_PRESENTED_STRENGTH_VAL, val);
		// 加体力
		target.addStrength(GameStaticConfig.presentStr, Cause.PRESENT);
		// 邮件提醒受赠者
		App.getApp().getServiceManager().get(MailService.class).sendSystemMail(
				target.getId(),
				MessageConst.BE_PRESENTED_STRENGTH_MAIL_TITLE,
				MessageFormat.format(MessageConst.BE_PRESENTED_STRENGTH_MAIL_CONTENT, source.getName(), source.getId(), new Date(), GameStaticConfig.presentStr));
		return null;
	}
	
	/**
	 * 获取玩家星级
	 * @param player
	 * @return
	 */
	public static int getStarLevel(Player player) {
		DestinyTemplate dt = App.getApp().getServiceManager().get(PlayerTrainService.class).getDestinyTemplate(player.getDestinyLvl());
		return dt != null ? dt.getStarLvl() : 0;
	}
	
	public static ExpCalc2 getExpCalc() {
		return expCalc;
	}
	
}
